#pragma once

class PALEGEM_API pgVec3
{
public:

	pgVec3();
	pgVec3(float fX, float fY, float fZ);
	pgVec3(int nX, int nY, int nZ);
	pgVec3(const XMVECTOR &v);

	~pgVec3();

	float Dot(const pgVec3 &v1);

	float Length();
	float LengthSquared();

	pgVec3 Normalize();
	
	static pgVec3 Cross(const pgVec3 &v1, const pgVec3 &v2)
	{
		return pgVec3(v1.y * v2.z - v1.z * v2.y,
			v1.z * v2.x - v1.x * v2.z,
			v1.x * v2.y - v1.y * v2.x);
						
	}

	float GetX() {return x;}
	float GetY() {return y;}
	float GetZ() {return z;}

	void Set(float fX, float fY, float fZ) { x = fX; y = fY; z = fZ;}

	void SetX(float fX) { x = fX; }
	void SetY(float fY) { y = fY; }
	void SetZ(float fZ) { z = fZ; }

	pgVec3 operator + (const pgVec3 &v1)	
	{
		return pgVec3(v1.x + x, v1.y + y, v1.z + z); 
	}

	void operator += (const pgVec3 &v1)
	{
		x += v1.x;
		y += v1.y;
		z += v1.z;
	}

	pgVec3 operator - (const pgVec3 &v1)	
	{
		return pgVec3(v1.x - x, v1.y - y, v1.z - z); 
	}

	void operator -= (const pgVec3 &v1)
	{
		x -= v1.x;
		y -= v1.y;
		z -= v1.z;
	}

	pgVec3 operator * (const float s)
	{
		return pgVec3(x * s, y * s, z * s);
	}

	pgVec3 operator / (const float s)
	{
		if (s == 0)
		{
			PG_LOG_WARNING_EX(TOPIC_PGGAME_APP, "Dividing pgVector by zero scalar! Using 1!");
			return pgVec3(x, y, z);
		}

		return pgVec3(x / s, y / s, z / s);
	}

	void operator *= (const float s)
	{
		x *= s;
		y *= s;
		z *= s;
	}

	void operator /= (const float s)
	{
		if (s == 0)
		{
			PG_LOG_WARNING_EX(TOPIC_PGGAME_APP, "Dividing pgVector by zero scalar! Using 1!");
			return;
		}

		x /= s;
		y /= s;
		z /= s;
	}

	bool operator == (const pgVec3 &v1)
	{
		return x == v1.x && y == v1.y && z == v1.z;
	}

	bool operator != (const pgVec3 &v1)
	{
		return x != v1.x || y != v1.y || z != v1.z;
	}

	operator XMVECTOR ()
	{
		return XMVectorSet(x, y, z, 1);
	}
private:
	
	float x, y, z;

};



